from flask import Flask
from flask_restful import Resource, Api, reqparse
from db_connector.conn import Conn
from collections import Counter
from datetime import date
from operator import itemgetter
from flask_cors import CORS
import json
import statistics
import redis


app = Flask(__name__)
cors = CORS(app, resources={r"*": {"origins": "*"}})
api = Api(app)
pool = redis.ConnectionPool(host='127.0.0.1')   #实现一个连接池
r = redis.Redis(connection_pool=pool)


# # 解决跨域问题
# class TabrResource(Resource):
#     def options(self):
#         return {'Allow': '*'}, 200, {'Access-Control-Allow-Origin': '*',
#                                      'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, DELETE, PUT',
#                                      'Access-Control-Allow-Headers': 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild',
#                                      }


# 获取所有站点数据，仅支持get方法
class AllData(Resource):
    def get(self):
        """
        需要提供
        （1）	SITEID（站点ID）
        （2）	SITENAME（站点名称）
        （3）	LONGITUDE（经度）
        （4）	LATITUDE（纬度）
        （5）	AIRLEVELCODE（清新等级编码）
        （6）	AIRLEVELNAME（清新等级名称）
        （7）	COLLECTTIME（监测时间）
        （8）	LASTUPDATETIME（最近更新时间）
        （9）	COL1（负氧离子值）
        （10）	MAXCOL1（当日负氧离子最高值）（根据当日的COL1求出MAXCOL1，并可以从后端读取到）
        （11）	SITEARR（站点类型）（需要添加到后端请求的数据中）
        """
        # 变量初始化
        result_json = {}
        result_json = json.loads(r.get("get_all_data"))
        return result_json


# 获取当前城市下所有站点
class CurrentCityAllSites(Resource):
    def post(self):
        """
        可以获取以下信息：
        （1）city（城市名称）
        （2）SITEID（站点ID）
        （3）SITENAME（站点名称）
        （4）COL1（负氧离子值）
        （5）MAXCOL1（当日负氧离子最高值）（根据当日的COL1求出MAXCOL1，可以从后端读取到）
        （6）LONGITUDE（经度）
        （7）LATITUDE（纬度）
        （8）AIRLEVELCODE（清新等级编码）
        （9）AIRLEVELNAME（清新等级名称）
        （10）COLLECTTIME（监测时间）
        （11）LASTUPDATETIME（最近更新时间）
        （12）SITEARR（站点类型）
        """
        parser = reqparse.RequestParser()
        parser.add_argument(
            'city', type=str, help="所查询城市名称错误，此项必填，请检查", required=True)  # 必填
        args = parser.parse_args()
        result_json = {}
        result_json['data'] = []
        city = args['city']
        all_city_data = json.loads(r.get("currentcity"))
        for k, v in all_city_data[city].items():
            result_json['data'].append(v)
        return result_json


# 搜索接口，仅支持post方法
class SearchResult(Resource):
    def post(self):
        """
        根据前端选择的city（城市名称）、
        AIRLEVELNAME(清新等级名称)、
        searchDayTime（查询时间）
        查询相应站点。
        需要获取站点如下信息：
        （1）	SITENAME
        （2）	SITEID
        （3）	AIRLEVELNAME
        （4）	COL1
        （5）	COL2
        （6）	COL3
        （7）	SITEARR
        """
        # 初始化
        parser = reqparse.RequestParser()
        parser.add_argument(
            'city', type=str, help="所查询城市名称错误，此项必填，请检查", required=True)  # 必填
        parser.add_argument('searchDayTime', type=str,
                            help="所查询时间错误， 格式为yyyy-mm-dd, 请检查", required=True)  # 必填
        parser.add_argument('AIRLEVELNAME', type=str, help="查询等级")  # str
        args = parser.parse_args()
        result_json = {}
        city_site_json = {}
        result_json['data'] = []
        city = args['city']
        # 时间取每天0点的数据，不然有重复出现
        search_date = args['searchDayTime']
        airlevelname = args['AIRLEVELNAME']
        conn = Conn("47.92.212.63", 3306,
                    "releaseplatform", "root", "bjfu1022")
        # 先根据城市，拿到该城市下的所有站点的code
        # sql_get_site = "select distinct * from site_data where DISTRICT = '%s';" % city
        # result_site = conn.execute_sql(sql_get_site)
        site_code_list = []
        city_site_json = json.loads(r.get("currentcity"))
        for k, v in city_site_json.items():
            if k == city:
                site_code_list = list(v.keys())
        # 拿到code后，再根据时间和质量等级进行查询
        sql_get_result = ""
        for site_code in site_code_list:
            sql_get_result = "select * from rp_data where DATE_FORMAT(COLLECTTIME, '%%Y-%%m-%%d') = '%s' and AIRLEVELNAME = '%s' and SITECODE = '%s' ;" % (
                search_date, airlevelname, site_code)
            # 用一个临时变量存储暂时结果
            print("开始执行sql，sitecode: ", site_code)
            print("当前sql ", sql_get_result)
            temp_result = conn.execute_sql(sql_get_result)
            if temp_result == ():
                # 如果查询结果为空，则调过此次的结果
                pass
            else:
                # 如果有一个站点有多个数据，取最新的数据
                temp_json = {}
                temp_json['city'] = city
                temp_json['searchDayTime'] = search_date
                temp_json['AIRLEVELNAME'] = airlevelname
                temp_json['SITENAME'] = temp_result[-1][17]
                temp_json['SITEID'] = temp_result[-1][16]
                temp_json['COL1'] = temp_result[-1][3]
                temp_json['COL2'] = temp_result[-1][4]
                temp_json['COL3'] = temp_result[-1][5]
                result_json['data'].append(temp_json)
        return result_json


class AllCity(Resource):
    def get(self):
        """
        获取信息如下：
        （1）	DISTRICT（城市名）
        （2）	AIRLEVELCODE（清新等级编码）
        （3）	AIRLEVELNAME（清新等级名称）
        （4）	COL1（负氧离子值）
        （5）	MAXCOL1（当日负氧离子最高值）（根据当日的COL1求出MAXCOL1，并可以从后端读取到）
        （6）	COLLECTTIMES（监测时间）
        （7）	LASTUPDATETIME（最近更新时间）
        """
        result_json = {}
        result_json = json.loads(r.get("all_city"))
        return result_json


class AllCityRanking(Resource):
    def get(self):
        # 获取当日站点空气数据排行和该站点当日最大的col1
        # 先从站点库里，查询出所有站点的sitecode和名称
        # 再去空气数据库里查出，每个站点当日最新的col1及截止当前的maxcol1
        # 根据col1去排序，取出前十
        # 变量初始化
        result_json = {}
        result_json = json.loads(r.get("ranking"))
        return result_json


class CityHourEvaluation(Resource):
    def get(self):
        result_json = dict()
        result_json = json.loads(r.get("city_hour_evaluation"))
        return result_json



class CityDayEvaluation(Resource):
    def get(self):
        result_json = dict()
        result_json = json.loads(r.get("city_day_evaluation"))
        return result_json


class CityMonthEvaluation(Resource):
    def get(self):
        result_json = dict()
        result_json = json.loads(r.get("city_month_evaluation"))
        return result_json


class CityLast7days(Resource):
    # 所有站点的前一日的COL1、COL2、COL3的平均值、最近七天COL1平均值的最大值。
    def get(self):
        result_json = dict()
        result_json = json.loads(r.get("citylast7days"))
        return result_json


class CityQuarterlyData(Resource):
    # 获取所有城市的季度数据”
    def get(self):
        result_json = dict()
        result_json = json.loads(r.get("cityquarterlydata"))
        return result_json


class HistoricalAirData(Resource):
    # 用以展示所有站点24小时、7天（的历史数据
    # 空气清新等级-ALRVALUE、负氧离子-COL1、PM2.5-COL2、O3-COL3）。
    def post(self):
        # timeType=1为24小时，timeType=2为7天
        parser = reqparse.RequestParser()
        parser.add_argument(
            'timeType', type=int, help="时间类型错误，此项必填，请检查", required=True)
        args = parser.parse_args()
        result_json = dict()
        timeType = args["timeType"]
        if timeType == 1:
            result_json = json.loads(r.get("all_site_24hours_data"))
            return result_json
        if timeType == 2:
            result_json = json.loads(r.get("all_site_7days_data"))
            return result_json
            
class SearchResultByCode(Resource):
    def post(self):
        """
        根据前端选择的siteCode（站点code）、
        AIRLEVELNAME(清新等级名称)、
        searchDayTime（查询时间）
        查询相应站点。
        需要获取站点如下信息：
        （1）	SITENAME
        （2）	SITEID
        （3）	AIRLEVELNAME
        （4）	COL1
        （5）	COL2
        （6）	COL3
        （7）	SITEARR
        """
        # 初始化
        parser = reqparse.RequestParser()
        parser.add_argument(
            'siteCode', type=str, help="所查询siteCode名称错误，此项必填，请检查", required=True)  # 必填
        parser.add_argument('searchDayTime', type=str,
                            help="所查询时间错误， 格式为yyyy-mm-dd, 请检查", required=True)  # 必填
        parser.add_argument('AIRLEVELNAME', type=str, help="查询等级")  # str
        args = parser.parse_args()
        result_json = {}
        result_json['data'] = []
        siteCode = args['siteCode']
        search_date = args['searchDayTime']
        airlevelname = args['AIRLEVELNAME']
        conn = Conn("47.92.212.63", 3306,
                    "releaseplatform", "root", "bjfu1022")
        # 先根据城市，拿到该城市下的所有站点的code
        # sql_get_site = "select distinct * from site_data where DISTRICT = '%s';" % city
        # result_site = conn.execute_sql(sql_get_site)
        # 拿到code后，再根据时间和质量等级进行查询
        sql_get_result = ""
        sql_get_result = "select * from rp_data where DATE_FORMAT(COLLECTTIME, '%%Y-%%m-%%d') = '%s' and AIRLEVELNAME = '%s' and SITECODE = '%s' ;" % (
            search_date, airlevelname, siteCode)
        # 用一个临时变量存储暂时结果
        print("开始执行sql，sitecode: ", siteCode)
        print("当前sql ", sql_get_result)
        temp_result = conn.execute_sql(sql_get_result)
        if temp_result == ():
            # 如果查询结果为空，则调过此次的结果
            pass
        else:
            # 如果有一个站点有多个数据，取最新的数据
            temp_json = {}
            temp_json['siteCode'] = siteCode
            temp_json['searchDayTime'] = search_date
            temp_json['AIRLEVELNAME'] = airlevelname
            temp_json['SITENAME'] = temp_result[-1][17]
            temp_json['SITEID'] = temp_result[-1][16]
            temp_json['COL1'] = temp_result[-1][3]
            temp_json['COL2'] = temp_result[-1][4]
            temp_json['COL3'] = temp_result[-1][5]
            result_json['data'].append(temp_json)
        return result_json



api.add_resource(AllData, '/get_all_data') # 此方法为get方法
api.add_resource(SearchResult, '/search') # post方法
api.add_resource(SearchResultByCode, '/searchByCode') # post方法
api.add_resource(CurrentCityAllSites, '/currentcity')
api.add_resource(AllCity, '/all_city')
api.add_resource(AllCityRanking, '/ranking')
api.add_resource(CityHourEvaluation, '/city_hour_evaluation')
api.add_resource(CityDayEvaluation, '/city_day_evaluation')
api.add_resource(CityMonthEvaluation, '/city_month_evaluation')
api.add_resource(CityLast7days, '/city_last7days')
api.add_resource(CityQuarterlyData, '/city_quarterly_data')
api.add_resource(HistoricalAirData, '/historical_airdata') # post方法






if __name__ == "__main__":
    app.run("0.0.0.0", 4396, True)
